import blue
import uthread
import uix
import uiutil
import xtriui
import form
import util
import listentry
import draw
import uiconst
import uicls
import calendar
NUM_DAYROWS = 6

class CalendarWnd(uicls.Window):
    __guid__ = 'form.eveCalendarWnd'
    __notifyevents__ = []

    def ApplyAttributes(self, attributes):
        uicls.Window.ApplyAttributes(self, attributes)
        sm.RegisterNotify(self)
        self.SetTopparentHeight(0)
        self.SetCaption(mls.UI_CAL_CALENDAR)
        self.SetMinSize([580, 400])
        self.SetWndIcon('ui_94_64_12')
        self.sr.leftSide = uicls.Container(name='leftSide', parent=self.sr.main, align=uiconst.TOLEFT, pos=(0, 0, 150, 0), padding=(const.defaultPadding,
         const.defaultPadding,
         0,
         const.defaultPadding))
        cont = uicls.Container(name='xDivider', parent=self.sr.main, align=uiconst.TOLEFT, pos=(0,
         0,
         const.defaultPadding,
         0), state=uiconst.UI_NORMAL)
        self.sr.xDivider = xtriui.Divider(cont)
        self.sr.xDivider.Startup(self.sr.leftSide, 'width', 'x', 75, 200)
        self.sr.xDivider.OnSizeChanging = self.OnLeftSideChanged
        self.sr.calendarForm = form.eveCalendar(pos=(0, 0, 0, 0), parent=self.sr.main, padding=(const.defaultPadding,
         const.defaultPadding,
         (2 * const.defaultPadding),
         const.defaultPadding))
        self.sr.leftSideTop = uicls.Container(name='leftSideTop', parent=self.sr.leftSide, align=uiconst.TOTOP, pos=(0, 0, 0, 40))
        uicls.Frame(parent=self.sr.leftSide, color=(1.0, 1.0, 1.0, 0.25))
        self.sr.cbCont = uicls.Container(name='cbCont', parent=self.sr.leftSide, align=uiconst.TOBOTTOM, pos=(0, 0, 0, 125), clipChildren=True)
        self.sr.leftSideBottom = uicls.Container(name='leftSideBottom', parent=self.sr.leftSide, align=uiconst.TOALL, pos=(0, 0, 0, 0))
        self.sr.leftSideBottom.OnResize = self.OnResizeLeftSideBottom
        self.sr.updatedCont = uicls.Container(name='updatedCont', parent=self.sr.leftSideBottom, align=uiconst.TOBOTTOM, pos=(0, 0, 0, 50))
        cont = uicls.Container(name='yDivider', parent=self.sr.leftSideBottom, align=uiconst.TOBOTTOM, pos=(0,
         0,
         0,
         const.defaultPadding), state=uiconst.UI_NORMAL)
        uicls.Line(parent=cont, align=uiconst.TOTOP)
        self.sr.yDivider = xtriui.Divider(cont)
        self.sr.yDivider.Startup(self.sr.updatedCont, 'height', 'y', 50, 205)
        self.sr.yDivider.OnSizeChanged = self.OnListsSizeChanged
        self.sr.todoCont = uicls.Container(name='todoCont', parent=self.sr.leftSideBottom, align=uiconst.TOALL, pos=(0, 0, 0, 0))
        uix.GetContainerHeader(mls.UI_CAL_TODO, self.sr.todoCont, 0)
        self.sr.toDoForm = uicls.EventList(pos=(0, 0, 0, 0), parent=self.sr.todoCont, name='toDoForm', listentryClass='CalendarListEntry', getEventsFunc=sm.GetService('calendar').GetMyNextEvents, header=mls.UI_CAL_TODO)
        uix.GetContainerHeader(mls.UI_CAL_UPDATEDEVENTS, self.sr.updatedCont, 1)
        uicls.Line(parent=self.sr.updatedCont, align=uiconst.TOBOTTOM)
        self.sr.changesForm = uicls.UpdateEventsList(pos=(0, 0, 0, 0), parent=self.sr.updatedCont, name='changesForm', listentryClass='CalendarUpdatedEntry', getEventsFunc=sm.GetService('calendar').GetMyChangedEvents, header=mls.UI_CAL_UPDATEDEVENTS)
        self.AddCheckBoxes()
        cont = uicls.Container(name='tabs', parent=self.sr.cbCont, align=uiconst.TOTOP, pos=(0, 10, 0, 36))
        uicls.Checkbox(text=mls.UI_CAL_SHOWDECLINED, parent=cont, configName='showDeclined', retval=0, checked=settings.user.ui.Get('calendar_showDeclined', 1), groupname=None, align=uiconst.TOPLEFT, pos=(6, 0, 200, 0), callback=self.DisplayCheckboxesChecked)
        uicls.Checkbox(text=mls.UI_CAL_SHOWTIMESTAMP, parent=cont, configName='showTimestamp', retval=0, checked=settings.user.ui.Get('calendar_showTimestamp', 1), groupname=None, align=uiconst.TOPLEFT, pos=(6, 18, 200, 0), callback=self.DisplayCheckboxesChecked)
        self.sr.cbCont.height += ((cont.height + cont.top) + 18)
        newEvent = uicls.Button(parent=self.sr.leftSideTop, label=mls.UI_CAL_NEW_EVENT, func=self.CreateNewEvent, pos=(0, 7, 0, 0))
        self.sr.todayBtn = today = uicls.Button(parent=self.sr.leftSideTop, label=mls.UI_CAL_TODAY, func=self.GetToday, pos=(0, 7, 0, 0))
        today.anchors = uiconst.UI_ANCHRIGHT



    def AddCheckBoxes(self, *args):
        uix.Flush(self.sr.cbCont)
        uix.GetContainerHeader(mls.UI_GENERIC_FILTERS, self.sr.cbCont, 0)
        checkboxInfo = [(mls.UI_CAL_GROUPPERSONCAL,
          'personal',
          const.calendarTagPersonal,
          settings.user.ui.Get(('calendarTagCheked_%s' % const.calendarTagPersonal), 1))]
        if (session.corpid and (not util.IsNPC(session.corpid))):
            checkboxInfo.append((mls.UI_CAL_GROUPCORP,
             'corp',
             const.calendarTagCorp,
             settings.user.ui.Get(('calendarTagCheked_%s' % const.calendarTagCorp), 1)))
        if session.allianceid:
            checkboxInfo.append((mls.UI_CAL_GROUPALLIANCE,
             'alliance',
             const.calendarTagAlliance,
             settings.user.ui.Get(('calendarTagCheked_%s' % const.calendarTagAlliance), 1)))
        checkboxInfo.append((mls.UI_CAL_GROUPCCP,
         'ccp',
         const.calendarTagCCP,
         settings.user.ui.Get(('calendarTagCheked_%s' % const.calendarTagCCP), 1)))
        self.sr.checkboxes = []
        for (label, config, tag, checked,) in checkboxInfo:
            cont = uicls.Container(name='tabs', parent=self.sr.cbCont, align=uiconst.TOTOP, pos=(0, 0, 0, 18))
            cb = uicls.Checkbox(text=label, parent=cont, configName=config, retval=tag, checked=checked, groupname=None, align=uiconst.TOPLEFT, pos=(6, 0, 200, 0), callback=self.CheckboxChecked)
            self.sr.checkboxes.append(cb)

        self.sr.cbCont.height = (len(self.sr.checkboxes) * 18)



    def CheckboxChecked(self, *args):
        showTags = 0
        for cb in self.sr.checkboxes:
            tag = cb.data.get('value', 0)
            if (cb.checked == True):
                showTags += tag
            settings.user.ui.Set(('calendarTagCheked_%s' % tag), cb.checked)

        sm.ScatterEvent('OnCalendarFilterChange')



    def DisplayCheckboxesChecked(self, cb):
        config = ('calendar_%s' % cb.name)
        settings.user.ui.Set(config, cb.checked)
        sm.ScatterEvent('OnCalendarFilterChange')



    def CreateNewEvent(self, *args):
        day = self.sr.calendarForm.selectedDay
        if (day and (not sm.GetService('calendar').IsInPast(day.year, day.month, day.monthday, allowToday=1))):
            year = day.year
            month = day.month
            monthday = day.monthday
        else:
            eve.Message('CalendarCannotPlanThePast2')
            now = blue.os.GetTime()
            (year, month, wd, monthday, hour, min, sec, ms,) = util.GetTimeParts(now)
        if not sm.GetService('calendar').IsInPast(year, month, monthday, allowToday=1):
            sm.GetService('calendar').OpenNewEventWnd(year, month, monthday)



    def GetToday(self, *args):
        self.sr.calendarForm.ResetBrowse()
        self.sr.calendarForm.InsertData()



    def OnLeftSideChanged(self, *args):
        if (self.sr.leftSide.width < 140):
            self.sr.todayBtn.state = uiconst.UI_HIDDEN
        else:
            self.sr.todayBtn.state = uiconst.UI_NORMAL



    def OnListsSizeChanged(self, *args):
        h = self.sr.updatedCont.height
        (l, t, w, absHeight,) = self.sr.leftSideBottom.GetAbsolute()
        if (h > absHeight):
            h = absHeight
            ratio = (float(h) / absHeight)
            settings.user.ui.Set('calendar_listRatio', ratio)
            self._OnResize()
            return 
        ratio = (float(h) / absHeight)
        settings.user.ui.Set('calendar_listRatio', ratio)



    def OnResizeLeftSideBottom(self, *args):
        if (self and ((not self.destroyed) and util.GetAttrs(self, 'sr', 'updatedCont'))):
            (l, t, w, absHeight,) = self.sr.leftSideBottom.GetAbsolute()
            scrollHeight = (absHeight - 64)
            ratio = settings.user.ui.Get('calendar_listRatio', 0.5)
            h = int((ratio * absHeight))
            if (h > scrollHeight):
                h = scrollHeight
            self.sr.updatedCont.height = max(64, h)
            self.sr.yDivider.max = scrollHeight
        uthread.new(self.UpdateIndicators)



    def UpdateIndicators(self, *args):
        blue.pyos.synchro.Yield()
        self.sr.changesForm.UpdateMoreIndicators()
        self.sr.toDoForm.UpdateMoreIndicators()



    def OnResize(self, *args):
        uicls.Window._OnResize(self)
        self.sr.calendarForm._OnResize()
        self.sr.changesForm.OnResize()
        self.sr.toDoForm.OnResize()



    def OnExpanded(self, *args):
        uthread.new(self.OnExpanded_thread)



    def OnExpanded_thread(self, *args):
        blue.pyos.synchro.Sleep(50)
        if (self and (not self.dead)):
            self.UpdateIndicators()




class Calendar(form.Calendar):
    __guid__ = 'form.eveCalendar'
    __notifyevents__ = ['OnReloadCalendar',
     'OnReloadEvents',
     'OnCalendarFilterChange']
    default_pos = (0, 0, 256, 256)

    def InsertBrowseControls(self, *args):
        self.sr.backBtn = btn = uix.GetBigButton(24, self.sr.monthTextCont, 0, 0)
        btn.OnClick = (self.ChangeMonth, -1)
        btn.hint = mls.UI_GENERIC_PREVIOUS
        uix.MapSprite('23_1', btn.sr.icon)
        self.sr.fwdBtn = btn = uix.GetBigButton(24, self.sr.monthTextCont, 0, 0)
        btn.OnClick = (self.ChangeMonth, 1)
        btn.hint = mls.UI_CMD_NEXT
        uix.MapSprite('23_2', btn.sr.icon)
        btn.anchors = uiconst.UI_ANCHRIGHT



    def AddMonthText(self, text = '', *args):
        if (self.sr.Get('monthText', None) is None):
            self.sr.monthText = uicls.Label(text=text, parent=self.sr.monthTextCont, left=0, fontsize=20, top=0, state=uiconst.UI_NORMAL, align=uiconst.CENTERTOP)
            self.sr.monthText.autoPos = uiconst.AUTOPOSXCENTER
        return self.sr.monthText



    def LoadEvents(self, *args):
        (yearInView, monthInView,) = self.yearMonthInView
        events = sm.GetService('calendar').GetEventsByMonthYear(monthInView, yearInView)
        showTag = sm.GetService('calendar').GetActiveTags()
        eventsByDates = {}
        for eventKV in events:
            if eventKV.isDeleted:
                continue
            (year, month, wd, day, hour, min, sec, ms,) = util.GetTimeParts(eventKV.eventDateTime)
            time = ('%02d:%02d' % (hour, min))
            eventKV.eventTimeStamp = time
            if ((showTag is None) or ((showTag & eventKV.flag) != 0)):
                eventsThisDay = eventsByDates.get(day, {})
                eventsThisDay[eventKV.eventID] = eventKV
                eventsByDates[day] = eventsThisDay

        for (date, eventsThisDay,) in eventsByDates.iteritems():
            self.LoadEventsToADay(date, eventsThisDay)





class CalendarDay(uicls.CalendarDayCore):
    __guid__ = 'uicls.CalendarDay'
    default_pos = (0, 0, 256, 256)
    default_name = 'CalendarDay'

    def AddMoreContFill(self, *args):
        (maincolor, backgroundcolor, component, componentsub,) = self.GetWindowColor()
        icon = uicls.Icon(icon='ui_38_16_229', parent=self.sr.moreCont, pos=(0, -3, 16, 16), align=uiconst.CENTERTOP, idx=0, ignoreSize=True)
        icon.OnClick = self.OnMoreClick



    def GetWindowColor(self, *args):
        return sm.GetService('window').GetWindowColors()



    def AddFill(self, *args):
        self.sr.fill = fill = draw.Background(self)
        fill.left = fill.width = fill.top = fill.height = 1
        self.sr.frame = uicls.Frame(parent=self, color=(0.5, 0.5, 0.5, 0.0))



    def AddDayNumber(self, text = '', *args):
        if (self.sr.Get('dayNumberText', None) is None):
            self.sr.dayNumberText = uicls.Label(text=text, parent=self.sr.dayNumberCont, state=uiconst.UI_DISABLED, left=1, align=uiconst.TOPRIGHT)
        return self.sr.dayNumberText



    def OnMoreClick(self, *args):
        sm.GetService('calendar').OpenSingleDayWnd('day', self.year, self.month, self.monthday, self.events)




class CalendarHeader(uicls.CalendarHeaderCore):
    __guid__ = 'uicls.CalendarHeader'
    default_pos = (0, 0, 256, 256)
    default_name = 'CalendarHeader'
    default_charID = None

    def AddDayNameText(self, text = '', *args):
        if (self.sr.Get('dayNameText', None) is None):
            self.sr.dayNameText = uicls.Label(text=text, parent=self.sr.dayNameCont, state=uiconst.UI_NORMAL, align=uiconst.CENTERBOTTOM)
        return self.sr.dayNameText




class CalendarEventEntry(uicls.CalendarEventEntryCore):
    __guid__ = 'uicls.CalendarEventEntry'

    def AddLabel(self, text, *args):
        self.sr.label = uicls.Label(text=text, parent=self, left=12, top=-1, state=uiconst.UI_DISABLED, color=None, align=uiconst.TOPLEFT, singleline=1, clipped=1)
        self.sr.label.autoPos = uix.AUTOPOSYCENTER



    def GetMenu(self):
        return self.MenuFunction(self)



    def MenuFunction(self, entry, *args):
        return []




class CalendarNewEventWnd(uicls.Window):
    __guid__ = 'form.CalendarNewEventWnd'
    __notifyevents__ = ['OnRespondToEvent']

    def ApplyAttributes(self, attributes):
        uicls.Window.ApplyAttributes(self, attributes)
        sm.RegisterNotify(self)
        year = attributes.year
        month = attributes.month
        monthday = attributes.monthday
        eventInfo = attributes.eventInfo
        edit = (attributes.edit or False)
        self.SetTopparentHeight(0)
        self.SetWndIcon('ui_94_64_12')
        self.HideMainIcon()
        self.SetMinSize([380, 370])
        now = blue.os.GetTime()
        (cyear, cmonth, cwd, cday, chour, cmin, csec, cms,) = util.GetTimeParts(now)
        if ((year is None) or (month is None)):
            year = cyear
            month = cmonth
        if ((year,
         month,
         monthday) == (cyear,
         cmonth,
         cday)):
            (year, month, monthday, hour,) = self.FindTimeToUse(year, month, monthday, chour)
        else:
            hour = 12
        self.year = year
        self.month = month
        self.monthday = monthday
        self.hour = hour
        self.min = 0
        self.configname = ('%s_%s_%s' % (year,
         month,
         monthday))
        self.quickFilterInput = None
        self.invitees = None
        self.oldInvitees = None
        self.inEditMode = False
        self.sr.infoCont = uicls.Container(name='infoCont', parent=self.sr.main, align=uiconst.TOTOP, pos=(0, 0, 0, 100))
        self.sr.bottom2 = uicls.Container(name='bottom2', parent=self.sr.main, align=uiconst.TOBOTTOM, pos=(0, 0, 0, 26))
        self.sr.tabCont = uicls.Container(name='tabCont', parent=self.sr.main, align=uiconst.TOALL, pos=(0, 0, 0, 0))
        self.sr.tabs = form.TabGroup(uicls.Container(name='tabs', parent=self.sr.tabCont, align=uiconst.TOTOP, pos=(0, 0, 0, 18)))
        self.sr.eventDescrCont = uicls.Container(name='invitedScroll', parent=self.sr.tabCont, align=uiconst.TOALL, pos=(0, 0, 0, 0))
        self.sr.invitedCont = uicls.Container(name='invitedScroll', parent=self.sr.tabCont, align=uiconst.TOALL, pos=(0, 0, 0, 0))
        subtabs = [[mls.UI_CAL_DESCRIPTION,
          self.sr.eventDescrCont,
          self,
          'descr']]
        flag = util.GetAttrs(eventInfo, 'flag')
        if ((flag is None) or (flag == const.calendarTagPersonal)):
            subtabs.append([mls.UI_CAL_INVITATIONS,
             self.sr.invitedCont,
             self,
             'invitations'])
        elif ((flag in [const.calendarTagCorp, const.calendarTagAlliance]) and (session.corpid and ((session.corprole & const.corpRoleChatManager) == const.corpRoleChatManager))):
            subtabs.append([mls.UI_CAL_INVITATIONS,
             self.sr.invitedCont,
             self,
             'invitations'])
        self.sr.tabs.Startup(subtabs, 'calenderEvent_tabs', autoselecttab=0)
        self.sr.tabs.ShowPanelByName(mls.UI_CAL_DESCRIPTION)
        invTab = self.sr.tabs.sr.Get(('%s_tab' % mls.UI_CAL_INVITATIONS), None)
        if (invTab is not None):
            invTab.OnTabDropData = self.OnDropData
        if (eventInfo is not None):
            eventDetails = sm.GetService('calendar').GetEventDetails(eventInfo.eventID, eventInfo.ownerID)
            self.eventID = eventInfo.eventID
            self.title = eventInfo.eventTitle
            self.descr = eventDetails.eventText
            self.creatorID = eventDetails.creatorID
            self.duration = eventInfo.eventDuration
            self.importance = eventInfo.importance
            self.eventTag = eventInfo.flag
            self.cbChecked = self.eventTag
            self.eventInfo = eventInfo
            (self.year, self.month, cwd, self.monthdayday, self.hour, self.min, sec, ms,) = util.GetTimeParts(eventInfo.eventDateTime)
            if edit:
                self.SetupCreateControls(new=(not edit))
            else:
                self.SetupReadOnlyElements()
        else:
            self.eventID = None
            self.title = ''
            self.descr = ''
            self.creatorID = None
            self.duration = 0
            self.importance = 0
            self.eventTag = const.calendarTagPersonal
            self.cbChecked = const.calendarTagPersonal
            self.eventInfo = None
            self.SetupCreateControls()



    def Load(self, key, *args):
        if (key == 'invitations'):
            self.LoadInviteeTabScroll()



    def LoadInviteeTabScroll(self, *args):
        if (getattr(self, 'eventID', None) is None):
            tag = self.cbChecked
        else:
            tag = self.eventTag
        if (tag == const.calendarTagCCP):
            return 
        if self.inEditMode:
            if (tag == const.calendarTagCorp):
                self.LoadCorpAllianceInScroll(session.corpid)
                return 
            if (tag == const.calendarTagAlliance):
                self.LoadCorpAllianceInScroll(session.allianceid)
                return 
        self.LoadInviteeScroll()



    def SetupCreateControls(self, new = 1, *args):
        self.inEditMode = True
        left = 6
        top = 20
        space = 10
        space2 = 30
        thisDay = [self.year,
         self.month,
         self.monthday,
         self.hour,
         self.min]
        uiutil.Flush(self.sr.infoCont)
        uiutil.Flush(self.sr.bottom2)
        btns = []
        if new:
            caption = mls.UI_CAL_NEW_EVENT
            btns.append([mls.UI_CMD_CREATE,
             self.CreateOrEditEvent,
             (1,),
             None])
        else:
            caption = mls.UI_CAL_EDITEVENT
            btns.append([mls.UI_CMD_SAVE,
             self.CreateOrEditEvent,
             (0,),
             None])
        btns.append([mls.UI_CMD_CANCEL,
         self.CloseX,
         (),
         None])
        self.SetCaption(caption)
        statebtns = uix.MakeBtnGroup(btns, where=self.sr.bottom2, idx=0)
        self.sr.titleEdit = uicls.SinglelineEdit(name='titleEdit', parent=self.sr.infoCont, setvalue=self.title, maxLength=const.calendarMaxTitleSize, pos=((left - 1),
         top,
         326,
         0), label=mls.UI_GENERIC_TITLE)
        top += 40
        now = blue.os.GetTime()
        (cyear, cmonth, cwd, cday, chour, cmin, csec, cms,) = util.GetTimeParts(now)
        yearRange = ((const.calendarViewRangeInMonths / 12) + 1)
        self.sr.fromDate = uix.GetDatePicker(self.sr.infoCont, setval=thisDay, left=5, top=top, idx=None, withTime=True, timeparts=4, startYear=cyear, yearRange=yearRange)
        durationOptions = [(mls.UI_SHARED_NOTSPECIFIED, None), (mls.UI_CAL_ONEHOUR, 60)]
        durationOptions += [ ((mls.UI_CAL_NUMHOURS % {'num': i}), (i * 60)) for i in xrange(2, 25) ]
        dLeft = ((self.sr.fromDate.left + self.sr.fromDate.width) + 16)
        self.sr.durationCombo = uicls.Combo(label=mls.UI_GENERIC_DURATION, parent=self.sr.infoCont, options=durationOptions, name='duration', select=self.duration, pos=(dLeft,
         top,
         0,
         0), width=90, align=uiconst.TOPLEFT)
        top += space2
        self.sr.cbCont2 = uicls.Container(name='cbCont2', parent=self.sr.infoCont, align=uiconst.TOTOP, pos=(0,
         top,
         0,
         20))
        self.sr.importantCB = uicls.Checkbox(text=mls.UI_GENERIC_IMPORTANT, parent=self.sr.cbCont2, configName='personal', retval=1, checked=self.importance, align=uiconst.TOPLEFT, pos=(6, 0, 200, 0))
        top += space2
        self.sr.eventTypeCont = uicls.Container(name='eventTypeCont', parent=self.sr.infoCont, align=uiconst.TOTOP, pos=(0, 0, 0, 200))
        cbTop = 0
        self.sr.radioBtns = []
        if new:
            checkboxes = [(mls.UI_CAL_GROUPPERSONCAL,
              'personal',
              const.calendarTagPersonal,
              (const.calendarTagPersonal == self.eventTag),
              cbTop)]
            cbTop += 18
            if (session.corpid and ((session.corprole & const.corpRoleChatManager) == const.corpRoleChatManager)):
                checkboxes.append((mls.UI_CAL_GROUPCORP,
                 'corp',
                 const.calendarTagCorp,
                 (const.calendarTagCorp == self.eventTag),
                 cbTop))
                cbTop += 18
            if (session.allianceid and ((session.corprole & const.corpRoleChatManager) == const.corpRoleChatManager)):
                checkboxes.append((mls.UI_CAL_GROUPALLIANCE,
                 'alliance',
                 const.calendarTagAlliance,
                 (const.calendarTagAlliance == self.eventTag),
                 cbTop))
                cbTop += 18
            for (label, config, tag, checked, cbtop,) in checkboxes:
                cb = uicls.Checkbox(text=label, parent=self.sr.eventTypeCont, configName=config, retval=tag, checked=checked, align=uiconst.TOPLEFT, pos=(6,
                 cbtop,
                 200,
                 0), groupname='eventTag', callback=self.TagCheckboxChecked)
                self.sr.radioBtns.append(cb)

        else:
            eventTypeH = uiutil.UpperCase(mls.UI_CAL_EVENTTYPE)
            eventType = sm.GetService('calendar').GetEventTypes().get(self.eventTag, '-')
            uicls.Label(text=eventTypeH, parent=self.sr.eventTypeCont, name='eventType', align=uiconst.TOPLEFT, top=cbTop, fontsize=10, letterspace=1, left=left, idx=1, state=uiconst.UI_NORMAL)
            uicls.Label(text=eventType, parent=self.sr.eventTypeCont, left=left, top=(cbTop + space), width=200, state=uiconst.UI_NORMAL)
            cbTop += 26
        self.sr.eventTypeCont.height = cbTop
        top += cbTop
        self.sr.infoCont.height = top
        uiutil.Flush(self.sr.eventDescrCont)
        descCont = uicls.Container(name='descCont', parent=self.sr.eventDescrCont, align=uiconst.TOALL, pos=(0, 0, 0, 0), padding=(const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding))
        self.sr.descrEdit = uix.GetTextedit(self.descr, where=descCont, align=uix.UI_ALCLIENT, maxLength=const.calendarMaxDescrSize)
        uiutil.Flush(self.sr.invitedCont)
        self.sr.addIviteeeBtnCont = uicls.Container(name='btnCont', parent=self.sr.invitedCont, align=uiconst.TOTOP, pos=(0, 0, 0, 26), state=uiconst.UI_HIDDEN)
        addBtn = uicls.Button(parent=self.sr.addIviteeeBtnCont, label=mls.UI_CAL_ADDINVITEE, func=self.OpenAddInvteeWnd, pos=(0, 6, 0, 0))
        if (new or (self.eventTag == const.calendarTagPersonal)):
            self.sr.addIviteeeBtnCont.state = uiconst.UI_PICKCHILDREN
        self.AddpQuickFilter(self.sr.addIviteeeBtnCont)
        self.sr.inviteScroll = uicls.Scroll(name='invitedScroll', parent=self.sr.invitedCont, padding=(const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding))
        content = self.sr.inviteScroll.sr.content
        content.OnDropData = self.OnDropData
        if (self.sr.tabs.GetSelectedArgs() == 'invitations'):
            self.LoadInviteeTabScroll()



    def TagCheckboxChecked(self, cb, *args):
        tag = cb.data.get('value', const.calendarTagPersonal)
        self.cbChecked = tag
        if (tag == const.calendarTagPersonal):
            self.sr.addIviteeeBtnCont.state = uiconst.UI_PICKCHILDREN
            self.LoadInviteeScroll()
        else:
            self.sr.addIviteeeBtnCont.state = uiconst.UI_HIDDEN
            if (tag == const.calendarTagCorp):
                self.LoadCorpAllianceInScroll(session.corpid)
            elif (tag == const.calendarTagAlliance):
                self.LoadCorpAllianceInScroll(session.allianceid)



    def LoadCorpAllianceInScroll(self, entityID, *args):
        if (entityID is None):
            return 
        owner = cfg.eveowners.GetIfExists(entityID)
        if (owner is None):
            return 
        typeinfo = cfg.invtypes.Get(owner.typeID)
        if (typeinfo is not None):
            scrolllist = [listentry.Get('User', {'charID': entityID})]
            self.sr.inviteScroll.Load(contentList=scrolllist, headers=[], noContentHint='')



    def SetupReadOnlyElements(self, *args):
        left = 8
        secondCol = 150
        top = 6
        space = 10
        space2 = 30
        self.SetCaption(mls.UI_SHARED_EVENT)
        btns = []
        if ((not sm.GetService('calendar').IsInPastFromBlueTime(then=self.eventInfo.eventDateTime)) and (not self.eventInfo.isDeleted)):
            if (self.eventInfo.flag in [const.calendarTagCorp, const.calendarTagAlliance]):
                self.AddAcceptDeclineBtns(btns)
                if ((self.eventInfo.ownerID in [session.corpid, session.allianceid]) and ((session.corprole & const.corpRoleChatManager) == const.corpRoleChatManager)):
                    self.InsertEditDeleteBtns(btns)
            else:
                if (self.eventInfo.flag == const.calendarTagPersonal):
                    if (self.eventInfo.ownerID != session.charid):
                        self.AddAcceptDeclineBtns(btns)
                    else:
                        self.InsertEditDeleteBtns(btns)
        btns.append([mls.UI_CMD_CLOSE,
         self.CloseX,
         (),
         None])
        uiutil.Flush(self.sr.bottom2)
        statebtns = uix.MakeBtnGroup(btns, where=self.sr.bottom2, idx=0)
        title = uiutil.UpperCase(self.title)
        if (self.importance > 0):
            title = ('<color=red>!</color> %s' % title)
        titleCont = uicls.Container(name='titleCont', parent=self.sr.infoCont, align=uiconst.TOTOP, pos=(0, 0, 0, 30), clipChildren=True)
        uicls.Label(text=title, parent=titleCont, left=left, top=top, fontsize=20, state=uiconst.UI_NORMAL)
        top += 26
        startH = uiutil.UpperCase(mls.UI_CAL_STARTTIME)
        uicls.Label(text=startH, parent=self.sr.infoCont, name='startTime', align=uiconst.TOPLEFT, top=top, fontsize=10, letterspace=1, left=left, idx=1, state=uiconst.UI_NORMAL)
        startTime = util.FmtDate(self.eventInfo.eventDateTime, 'ls')
        uicls.Label(text=startTime, parent=self.sr.infoCont, left=left, top=(top + space), width=200, state=uiconst.UI_NORMAL)
        eventTypeH = uiutil.UpperCase(mls.UI_CAL_EVENTTYPE)
        uicls.Label(text=eventTypeH, parent=self.sr.infoCont, name='eventType', align=uiconst.TOPLEFT, top=top, fontsize=10, letterspace=1, left=secondCol, idx=1, state=uiconst.UI_NORMAL)
        eventType = sm.GetService('calendar').GetEventTypes().get(self.eventTag, '-')
        uicls.Label(text=eventType, parent=self.sr.infoCont, left=secondCol, top=(top + space), width=200, state=uiconst.UI_NORMAL)
        top += space2
        durationH = uiutil.UpperCase(mls.UI_GENERIC_DURATION)
        uicls.Label(text=durationH, parent=self.sr.infoCont, name='duration', align=uiconst.TOPLEFT, top=top, fontsize=10, letterspace=1, left=left, idx=1, state=uiconst.UI_NORMAL)
        if (self.eventInfo.eventDuration is None):
            durationLabel = mls.UI_SHARED_NOTSPECIFIED
        else:
            hours = (self.eventInfo.eventDuration / 60)
            if (hours > 1):
                durationLabel = (mls.UI_CAL_NUMHOURS % {'num': hours})
            else:
                durationLabel = mls.UI_CAL_ONEHOUR
        uicls.Label(text=durationLabel, parent=self.sr.infoCont, left=left, top=(top + space), width=200, state=uiconst.UI_NORMAL)
        creatorH = uiutil.UpperCase(mls.UI_GENERIC_CREATOR)
        creatorName = cfg.eveowners.Get(self.creatorID).name
        creatorLeft = secondCol
        if (self.eventTag == const.calendarTagCCP):
            creatorNameText = mls.UI_CAL_GROUPCCP
        else:
            creatorLeft -= 4
            creatorNameText = ('<url=localsvc:service=calendar&method=ShowCharacterInfo&itemID=%s> %s </url>' % (self.creatorID, creatorName))
        uicls.Label(text=creatorH, parent=self.sr.infoCont, name='eventType', align=uiconst.TOPLEFT, top=top, fontsize=10, letterspace=1, left=secondCol, idx=1, state=uiconst.UI_NORMAL)
        uicls.Label(text=creatorNameText, parent=self.sr.infoCont, top=(top + space), color=None, state=uiconst.UI_NORMAL, left=creatorLeft)
        top += space2
        (iconPath, myResponse,) = sm.GetService('calendar').GetMyResponseIconFromID(self.eventID, long=1, getDeleted=self.eventInfo.isDeleted)
        response = sm.GetService('calendar').GetResponseType().get(myResponse, mls.UI_GENERIC_UNKNOWN)
        statusH = uiutil.UpperCase(mls.UI_GENERIC_STATUS)
        uicls.Label(text=statusH, parent=self.sr.infoCont, name='status', align=uiconst.TOPLEFT, top=top, fontsize=10, letterspace=1, left=left, idx=1, state=uiconst.UI_NORMAL)
        self.sr.statusIconCont = uicls.Container(name='statusIconCont', parent=self.sr.infoCont, align=uiconst.TOPLEFT, pos=(left,
         (top + space),
         16,
         16))
        self.sr.reponseText = uicls.Label(text=response, parent=self.sr.infoCont, left=(left + 16), top=(top + space), width=200, state=uiconst.UI_NORMAL)
        if iconPath:
            icon = uicls.Icon(icon=iconPath, parent=self.sr.statusIconCont, align=uiconst.CENTER, pos=(0, 0, 16, 16))
        updateH = uiutil.UpperCase(mls.UI_CAL_LASTUPDATED)
        uicls.Label(text=updateH, parent=self.sr.infoCont, name='updated', align=uiconst.TOPLEFT, top=top, fontsize=10, letterspace=1, left=secondCol, idx=1, state=uiconst.UI_NORMAL)
        updateTime = util.FmtDate(self.eventInfo.dateModified, 'ls')
        uicls.Label(text=updateTime, parent=self.sr.infoCont, left=secondCol, top=(top + space), width=200, state=uiconst.UI_NORMAL)
        top += space2
        self.sr.infoCont.height = top
        descr = self.descr
        descCont = uicls.Container(name='descCont', parent=self.sr.eventDescrCont, align=uiconst.TOALL, pos=(0, 0, 0, 0), padding=(const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding))
        self.sr.descrEdit = uix.GetTextedit(descr, where=descCont, align=uix.UI_ALCLIENT, maxLength=1000, readonly=1)
        uiutil.Flush(self.sr.invitedCont)
        self.sr.searchCont = uicls.Container(name='searchCont', parent=self.sr.invitedCont, align=uiconst.TOTOP, pos=(0, 0, 0, 26))
        self.AddpQuickFilter(self.sr.searchCont)
        if (self.eventTag == const.calendarTagCCP):
            self.sr.searchCont.state = uiconst.UI_HIDDEN
        elif ((self.eventTag in [const.calendarTagCorp, const.calendarTagAlliance]) and (session.corpid and (not ((session.corprole & const.corpRoleChatManager) == const.corpRoleChatManager)))):
            self.sr.searchCont.state = uiconst.UI_HIDDEN
        self.sr.inviteScroll = uicls.Scroll(name='invitedScroll', parent=self.sr.invitedCont, pos=(0, 0, 0, 0), padding=(const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding))



    def InsertEditDeleteBtns(self, btns, top = 6, *args):
        editDeleteCont = uicls.Container(name='editCont', parent=self.sr.infoCont, align=uiconst.TORIGHT, pos=(0, 0, 30, 0))
        editBtn = uicls.Button(parent=editDeleteCont, label=mls.UI_CMD_EDIT, func=self.ChangeToEditMode, pos=(const.defaultPadding,
         top,
         0,
         0))
        editBtn.anchors = uiconst.UI_ANCHRIGHT
        deleteBtn = uicls.Button(parent=editDeleteCont, label=mls.UI_CMD_DELETE, func=self.Delete, pos=(const.defaultPadding,
         (top + 24),
         0,
         0))
        deleteBtn.anchors = uiconst.UI_ANCHRIGHT
        editBtn.width = deleteBtn.width = max(editBtn.width, deleteBtn.width)
        editDeleteCont.width = (4 + editBtn.width)



    def AddAcceptDeclineBtns(self, btns):
        (iconPath, myResponse,) = sm.GetService('calendar').GetMyResponseIconFromID(self.eventID)
        if (myResponse != const.eventResponseAccepted):
            btns.insert(0, [mls.UI_CMD_ACCEPT,
             self.RespondToEvent,
             (const.eventResponseAccepted),
             None])
        if (myResponse != const.eventResponseMaybe):
            btns.insert(1, [mls.UI_CAL_MAYBEREPLY,
             self.RespondToEvent,
             (const.eventResponseMaybe),
             None])
        if (myResponse != const.eventResponseDeclined):
            btns.insert(2, [mls.UI_CMD_DECLINE,
             self.RespondToEvent,
             (const.eventResponseDeclined),
             None])



    def AddpQuickFilter(self, cont, *args):
        self.sr.quickFilterClear = xtriui.MiniButton(uicls.Icon(icon='ui_73_16_210', parent=cont, pos=(11, 7, 0, 0), align=uiconst.TOPRIGHT), idx=0)
        self.sr.quickFilterClear.state = uix.UI_HIDDEN
        self.sr.quickFilterClear.Click = self.ClearQuickFilterInput
        self.sr.quickFilterClear.hint = mls.UI_CMD_CLEAR
        self.sr.quickFilterClear._OnMouseEnter = self.Nothing
        self.sr.quickFilterClear._OnMouseDown = self.Nothing
        self.sr.quickFilterClear._OnMouseUp = self.Nothing
        self.sr.quickFilterClear._OnMouseExit = self.Nothing
        self.sr.quickFilterClear._OnClick = self.sr.quickFilterClear.Click
        self.sr.quickFilterClear.keepselection = False
        self.sr.searchBox = uicls.SinglelineEdit(name='searchBox', parent=cont, setvalue='', maxLength=37, pos=(5, 6, 100, 0), label='', OnChange=self.SetQuickFilterInput)
        self.sr.searchBox.anchors = uiconst.UI_ANCHRIGHT
        self.sr.searchBox.SetHistoryVisibility(0)



    def OpenAddInvteeWnd(self, *args):
        actionBtn = [(mls.UI_CMD_ADD,
          self.AddInviteeToEvent,
          1)]
        caption = mls.UI_CAL_FINDINVITEES
        wnd = sm.GetService('window').GetWindow('searchWindow_calendar', 0, decoClass=form.SearchWindow)
        if wnd:
            wnd.CloseX()
        wnd = sm.GetService('window').GetWindow('searchWindow_calendar', 0, decoClass=form.SearchWindow)
        if wnd:
            wnd.CloseX()
        extraIconHintFlag = ['ui_73_16_13',
         mls.UI_CAL_CHARACTERADDED,
         False]
        wnd = sm.GetService('window').GetWindow('searchWindow_calendar', 1, decoClass=form.SearchWindow, actionBtns=actionBtn, caption=caption, input='', getMyCorp=False, getMyLists=False, getMyAlliance=False, showContactList=True, extraIconHintFlag=extraIconHintFlag, configname=self.configname)
        wnd.ExtraMenuFunction = self.InviteeMenuFunction
        wnd.IsAdded = self.CheckIfAdded



    def CheckIfAdded(self, contactID):
        if (self.invitees is None):
            self.PopulateInviteeDicts(self.eventID)
        return (contactID in self.invitees)



    def AddInviteeToEvent(self, func, *args):
        if (self.inEditMode is False):
            return 
        if ((not self) or self.destroyed):
            return 
        sel = apply(func)
        selIDs = [ each.charID for each in sel ]
        self.AddInvitees(selIDs)



    def AddInvitees(self, charIDList):
        if (self.inEditMode is False):
            return 
        if (self.invitees is None):
            self.PopulateInviteeDicts(self.eventID)
        for charID in charIDList:
            if ((charID == session.charid) or (charID is None)):
                continue
            if (len(self.invitees) >= const.calendarMaxInvitees):
                eve.Message('CustomInfo', {'info': (mls.UI_CAL_TOOMANYINVITEES % {'maxCharacters': const.calendarMaxInvitees})})
                break
            if (charID not in self.invitees):
                self.invitees[charID] = const.eventResponseUndecided
                sm.ScatterEvent('OnSearcedUserAdded', charID, self.configname)

        self.LoadInviteeScroll()



    def LoadInviteeScroll(self, *args):
        if (self.invitees is None):
            self.PopulateInviteeDicts(self.eventID)
        responseDict = sm.GetService('calendar').GetResponsesToEventInStatusDict(self.eventID, self.invitees)
        scrolllist = []
        responseCategoryList = [const.eventResponseAccepted,
         const.eventResponseMaybe,
         const.eventResponseDeclined]
        if (self.eventTag == const.calendarTagPersonal):
            responseCategoryList.insert(-1, const.eventResponseUndecided)
        for response in responseCategoryList:
            label = sm.GetService('calendar').GetResponseType().get(response, mls.UI_GENERIC_UNKNOWN)
            data = {'GetSubContent': self.GetResponseSubContent,
             'label': label,
             'cleanLabel': label,
             'id': ('calendarInvitees', response),
             'state': 'locked',
             'BlockOpenWindow': 1,
             'showicon': sm.GetService('calendar').GetResponseIconNum(response),
             'showlen': 1,
             'groupName': 'labels',
             'groupItems': responseDict[response],
             'noItemText': mls.UI_CAL_NOCHARACTER,
             'response': response,
             'DropData': self.DropUserOnGroup,
             'allowGuids': ['listentry.User',
                            'listentry.Sender',
                            'listentry.ChatUser']}
            scrolllist.append(listentry.Get('Group', data))

        self.sr.inviteScroll.Load(contentList=scrolllist, headers=[], noContentHint='')



    def GetResponseSubContent(self, data, *args):
        response = data.response
        scrolllist = []
        if (len(data.groupItems) > const.calendarMaxInviteeDisplayed):
            if (response == const.eventResponseDeclined):
                string = mls.UI_CAL_TOOMANYDECLINED
            else:
                string = mls.UI_CAL_TOOMANYACCEPTED
            label = (string % {'maxNum': const.calendarMaxInviteeDisplayed})
            return [listentry.Get('Generic', {'label': label,
              'sublevel': 1})]
        else:
            cfg.eveowners.Prime(data.groupItems)
            for charID in data.groupItems:
                if (response == const.eventResponseUninvited):
                    continue
                charinfo = cfg.eveowners.Get(charID)
                entry = listentry.Get('User', {'charID': charID,
                 'MenuFunction': self.InviteeMenuFunction})
                scrolllist.append((charinfo.name.lower(), entry))

            scrolllist = uiutil.SortListOfTuples(scrolllist)
            return scrolllist



    def InviteeMenuFunction(self, nodes, *args):
        m = []
        if (self.inEditMode is False):
            return m
        else:
            if (self.invitees is None):
                self.PopulateInviteeDicts(self.eventID)
            charIDs = [ node.charID for node in nodes if (node.charID in self.invitees) ]
            if (session.charid in charIDs):
                charIDs.remove(session.charid)
            numCharIDs = len(charIDs)
            if (numCharIDs > 0):
                label = mls.UI_CAL_REMOVEINVITEE
                if (numCharIDs > 1):
                    label = ('%s (%s)' % (label, numCharIDs))
                m = [(label,
                  self.RemoveInviteeFromScroll,
                  (charIDs))]
            return m



    def RemoveInviteeFromScroll(self, charIDs):
        if (self.inEditMode is False):
            return 
        if (self.invitees is None):
            self.PopulateInviteeDicts(self.eventID)
        for charID in charIDs:
            self.invitees.pop(charID, None)

        sm.ScatterEvent('OnSearcedUserRemoved', charIDs, self.configname)
        self.LoadInviteeScroll()



    def ChangeToEditMode(self, *args):
        self.FlushAll()
        if (self.invitees is None):
            self.PopulateInviteeDicts(self.eventID)
        self.oldInvitees = self.invitees.copy()
        self.SetupCreateControls(new=0)



    def FlushAll(self, *args):
        uiutil.Flush(self.sr.infoCont)
        uiutil.Flush(self.sr.eventDescrCont)
        uiutil.Flush(self.sr.invitedCont)
        uiutil.Flush(self.sr.bottom2)



    def FindTimeToUse(self, year, month, day, hour):
        (firstDay, lastDay,) = calendar.monthrange(year, month)
        hour = (hour + 1)
        if (hour > 23):
            hour = 0
            day = (day + 1)
        if (day > lastDay):
            day = 1
            month += 1
        if (month > const.calendarDecember):
            month = const.calendarJanuary
            year = (year + 1)
        return (year,
         month,
         day,
         hour)



    def CreateOrEditEvent(self, create = 1, *args):
        if getattr(self, 'editing', 0):
            return 
        self.editing = 1
        try:
            eventTag = 0
            for btn in self.sr.radioBtns:
                if btn.checked:
                    eventTag = btn.data['value']

            if (eventTag == 0):
                eventTag = self.eventTag
            descr = self.sr.descrEdit.GetValue()
            title = self.sr.titleEdit.GetValue()
            fromDate = self.sr.fromDate.GetValue()
            duration = self.sr.durationCombo.GetValue()
            important = self.sr.importantCB.checked
            (cyear, cmonth, cwd, cday, chour, cmin, csec, cms,) = util.GetTimeParts(fromDate)
            if sm.GetService('calendar').IsInPast(cyear, cmonth, cday, chour, cmin):
                raise UserError('CalendarCannotPlanThePast')
            if create:
                if (self.invitees is None):
                    self.PopulateInviteeDicts(self.eventID)
                newInviteeCharIDs = self.invitees.keys()
                sm.GetService('calendar').CreateNewEvent(fromDate, duration, title, descr, eventTag, important, invitees=newInviteeCharIDs)
            elif (self.invitees is None):
                self.PopulateInviteeDicts(self.eventID)
            newInviteeCharIDs = [ charID for charID in self.invitees.keys() if (charID not in self.oldInvitees.keys()) ]
            removedInviteeCharIDs = [ charID for charID in self.oldInvitees.keys() if (charID not in self.invitees.keys()) ]
            wasEdited = sm.GetService('calendar').EditEvent(self.eventID, self.eventInfo.eventDateTime, fromDate, duration, title, descr, eventTag, important)
            if not wasEdited:
                return 
            if ((len(newInviteeCharIDs) + len(removedInviteeCharIDs)) > 0):
                sm.GetService('calendar').UpdateEventParticipants(self.eventID, newInviteeCharIDs, removedInviteeCharIDs)

        finally:
            self.editing = 0

        sm.ScatterEvent('OnReloadEvents')
        self.CloseX()



    def RespondToEvent(self, response, *args):
        sm.GetService('calendar').RespondToEvent(self.eventID, self.eventInfo, response)



    def Delete(self, *args):
        wasDeleted = sm.GetService('calendar').DeleteEvent(self.eventID, self.eventInfo.ownerID)



    def Cancel(self, *args):
        self.CloseX()



    def OnDropData(self, dragObj, nodes, *args):
        toAdd = []
        for node in nodes:
            if ((node.__guid__ in ('listentry.User', 'listentry.Sender', 'listentry.ChatUser', 'listentry.SearchedUser')) and (node.IsCharacter and (not util.IsNPC(node.itemID)))):
                toAdd.append(node.itemID)

        if (len(toAdd) > 0):
            self.AddInvitees(toAdd)



    def DropUserOnGroup(self, groupID, nodes, *args):
        self.OnDropData(None, nodes)



    def OnClose_(self, *args):
        wnd = sm.GetService('window').GetWindow('searchWindow_calendar', 0, decoClass=form.SearchWindow)
        if (wnd and (wnd.configname == self.configname)):
            wnd.CloseX()



    def SetQuickFilterInput(self, *args):
        uthread.new(self._SetQuickFilterInput)



    def _SetQuickFilterInput(self):
        blue.synchro.Sleep(400)
        filter = self.sr.searchBox.GetValue()
        if (len(filter) > 0):
            self.quickFilterInput = filter.lower()
            self.sr.quickFilterClear.state = uix.UI_NORMAL
            if (len(filter) > 2):
                self.SearchInvitee()
            else:
                self.LoadInviteeScroll()
        else:
            prefilter = self.quickFilterInput
            self.quickFilterInput = None
            if (prefilter != None):
                self.LoadInviteeScroll()
            self.sr.quickFilterClear.state = uix.UI_HIDDEN



    def Nothing(self, *args):
        return 



    def ClearQuickFilterInput(self, *args):
        self.sr.searchBox.SetValue('')



    def SearchInvitee(self, *args):
        if (self.invitees is None):
            self.PopulateInviteeDicts(self.eventID)
        cfg.eveowners.Prime(self.invitees.keys())
        matched = uiutil.NiceFilter(self.QuickFilter, self.invitees.keys())
        extraIcons = {}
        for each in [const.eventResponseAccepted,
         const.eventResponseDeclined,
         const.eventResponseUndecided]:
            icon = sm.GetService('calendar').GetLongResponseIconPath(each)
            label = sm.GetService('calendar').GetResponseType().get(each, '')
            extraIcons[each] = [icon,
             label,
             True]

        scrolllist = []
        for charID in matched:
            contact = util.KeyVal(contactID=charID)
            response = self.invitees.get(charID, None)
            if (response is None):
                continue
            extraIconHintFlag = extraIcons.get(response, None)
            extraInfo = util.KeyVal(extraIconHintFlag=extraIconHintFlag, wndConfigname=self.configname)
            entryTuple = sm.GetService('addressbook').GetContactEntry(None, contact, extraInfo=extraInfo, listentryType='SearchedUser')
            scrolllist.append(entryTuple)

        scrolllist = uiutil.SortListOfTuples(scrolllist)
        self.sr.inviteScroll.Load(contentList=scrolllist, headers=[], noContentHint=mls.UI_GENERIC_NOTHINGFOUND)



    def QuickFilter(self, charID):
        name = cfg.eveowners.Get(charID).ownerName
        name = name.lower()
        return (name.find(self.quickFilterInput) > -1)



    def PopulateInviteeDicts(self, eventID):
        if (eventID is None):
            self.invitees = {}
        else:
            ownerID = util.GetAttrs(self, 'eventInfo', 'ownerID')
            self.invitees = sm.GetService('calendar').GetResponsesToEvent(eventID, ownerID)
        self.oldInvitees = self.invitees.copy()



    def OnRespondToEvent(self, *args):
        self.CloseX()




class CalendarSingleDayWnd(uicls.Window):
    __guid__ = 'form.CalendarSingleDayWnd'
    __notifyevents__ = ['OnReloadCalendar', 'OnCalendarFilterChange']

    def ApplyAttributes(self, attributes):
        uicls.Window.ApplyAttributes(self, attributes)
        config = attributes.config
        year = attributes.year
        month = attributes.month
        monthday = attributes.monthday
        events = attributes.events
        configname = attributes.configname
        isADay = (attributes.isADay or False)
        self.SetWndIcon('ui_94_64_12')
        self.config = config
        self.date = (year,
         month,
         monthday)
        self.year = year
        self.month = month
        self.monthday = monthday
        self.configname = configname
        self.isADay = isADay
        sm.RegisterNotify(self)
        if isADay:
            monthText = getattr(mls, ('UI_CAL_MONTH_%s' % month), '')
            caption = (mls.UI_CAL_DAYMONTHYEAR % {'month': monthText,
             'monthday': monthday,
             'year': year})
        else:
            caption = config
        self.SetCaption(caption)
        uix.WndCaption(caption, '', self.sr.topParent, align=uix.UI_ALNONE)
        self.SetMinSize([315, 300])
        btns = uix.MakeBtnGroup([[mls.UI_CMD_CLOSE,
          self.CloseX,
          (),
          None]], where=self.sr.main, idx=0)
        self.sr.eventScroll = uicls.Scroll(name='eventScroll', parent=self.sr.main, padding=(const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding,
         const.defaultPadding))
        self.sr.eventScroll.sr.id = 'calendar_singedaywnd'
        self.sr.eventScroll.sr.maxDefaultColumns = {mls.UI_GENERIC_TITLE: 150}
        self.LoadDaysEvents(events)



    def LoadDaysEvents(self, events, *args):
        self.events = events
        scrolllist = []
        includeUpdatedColumn = (self.config == mls.UI_CAL_UPDATEDEVENTS)
        for (eventID, event,) in events.iteritems():
            (iconPath, myResponse,) = sm.GetService('calendar').GetMyResponseIconFromID(eventID, long=1, getDeleted=event.isDeleted)
            if ((not settings.user.ui.Get('calendar_showDeclined', 1)) and (myResponse == const.eventResponseDeclined)):
                continue
            if (event.isDeleted and self.isADay):
                continue
            if self.isADay:
                timeStamp = getattr(event, 'eventTimeStamp', '')
            else:
                timeStamp = util.FmtDate(event.eventDateTime, 'ss')
            label = ('%s<t>%s' % (timeStamp, event.eventTitle))
            if includeUpdatedColumn:
                modified = util.FmtDate(event.dateModified, 'ss')
                label += ('<t>%s' % modified)
                sortBy = event.dateModified
            else:
                sortBy = event.eventDateTime
            data = util.KeyVal()
            data.label = label
            data.cleanLabel = label
            data.eventInfo = event
            data.eventID = event.eventID
            data.GetMenu = self.EventMenu
            data.iconPath = iconPath
            data.response = myResponse
            data.OnDblClick = self.DblClickEventEntry
            entry = listentry.Get('CalendarSingleDayEntry', data=data)
            scrolllist.append((sortBy, entry))

        scrolllist = uiutil.SortListOfTuples(scrolllist, reverse=includeUpdatedColumn)
        headers = [mls.UI_GENERIC_TIME, mls.UI_GENERIC_TITLE]
        if includeUpdatedColumn:
            headers.append(mls.UI_CAL_LASTUPDATED)
        self.sr.eventScroll.Load(contentList=scrolllist, headers=headers, noContentHint=mls.UI_CAL_NOPLANNEDEVENTS)



    def EventMenu(self, entry, *args):
        eventInfo = entry.sr.node.eventInfo
        m = sm.GetService('calendar').GetEventMenu(eventInfo, entry.sr.node.response)
        return m



    def DblClickEventEntry(self, entry, *args):
        eventInfo = entry.sr.node.eventInfo
        self.OpenEvent(eventInfo)



    def OpenEvent(self, eventInfo, *args):
        sm.GetService('calendar').OpenEventWnd(eventInfo)



    def OnReloadCalendar(self, *args):
        showTag = sm.GetService('calendar').GetActiveTags()
        if self.isADay:
            eventDict = {}
            events = sm.GetService('calendar').GetEventsByMonthYear(self.month, self.year)
            for eventKV in events:
                if eventKV.isDeleted:
                    continue
                (year, month, wd, day, hour, min, sec, ms,) = util.GetTimeParts(eventKV.eventDateTime)
                if (((year,
                 month,
                 day) == self.date) and ((showTag is None) or ((showTag & eventKV.flag) != 0))):
                    eventDict[eventKV.eventID] = eventKV
                else:
                    continue

            self.events = eventDict
            self.LoadDaysEvents(eventDict)
        elif (self.config == mls.UI_CAL_TODO):
            events = sm.GetService('calendar').GetMyNextEvents()
            self.events = events
            self.LoadDaysEvents(events)
        elif (self.config == mls.UI_CAL_UPDATEDEVENTS):
            events = sm.GetService('calendar').GetMyChangedEvents()
            self.events = events
            self.LoadDaysEvents(events)



    def OnCalendarFilterChange(self, *args):
        self.OnReloadCalendar()




class CalendarSingleDayEntry(listentry.Generic):
    __guid__ = 'listentry.CalendarSingleDayEntry'

    def Startup(self, *args):
        self.sr.statusIconCont = uicls.Container(name='statusIconCont', parent=self, align=uiconst.TOPLEFT, pos=(0, 0, 16, 16))
        self.sr.flagIconCont = uicls.Container(name='statusIconCont', parent=self, align=uiconst.TOPRIGHT, pos=(0, 0, 14, 14))
        uicls.Frame(parent=self.sr.flagIconCont)
        listentry.Generic.Startup(self, args)



    def Load(self, node):
        listentry.Generic.Load(self, node)
        self.sr.label.left = 16
        self.LoadStatusIcon(node)
        sm.GetService('calendar').LoadTagIconInContainer(node.eventInfo.flag, self.sr.flagIconCont)
        if (node.eventInfo.importance > 0):
            self.UpdateLabel(node)
        node.Set(('sort_%s' % mls.UI_GENERIC_TIME), node.eventInfo.eventDateTime)
        self.hint = sm.GetService('calendar').GetEventHint(node.eventInfo, node.response)



    def LoadStatusIcon(self, data):
        uiutil.Flush(self.sr.statusIconCont)
        icon = uicls.Icon(icon=data.iconPath, parent=self.sr.statusIconCont, align=uiconst.CENTERLEFT, pos=(0, 0, 16, 16))
        icon.hint = sm.GetService('calendar').GetResponseType().get(data.response, mls.UI_GENERIC_UNKNOWN)



    def UpdateLabel(self, data):
        label = data.cleanLabel
        label = ('<color=red>!</color> %s' % label)
        self.sr.label.text = label
        self.sr.node.label = label




class EventList(uicls.EventListCore):
    __guid__ = 'uicls.EventList'

    def SetupScroll(self, *args):
        self.sr.eventScroll = uicls.Scroll(name='eventScroll', parent=self)
        self.sr.eventScroll.scrollEnabled = 0
        self.sr.eventScroll.multiSelect = 0



    def LoadScroll(self, scrolllist, *args):
        scrolllist = scrolllist[:self.maxEntries]
        self.sr.eventScroll.Load(contentList=scrolllist, headers=[], noContentHint='')



    def AddMoreContFill(self, *args):
        draw.Background(self.sr.moreCont)
        icon = uicls.Icon(icon='ui_38_16_229', parent=self.sr.moreCont, pos=(0, -3, 16, 16), align=uiconst.CENTERTOP, idx=0, ignoreSize=True)
        icon.OnClick = self.OnMoreClick



    def GetEventEntry(self, eventInfo, *args):
        showTag = sm.GetService('calendar').GetActiveTags()
        if ((showTag is not None) and ((showTag & eventInfo.flag) == 0)):
            return 
        else:
            (icon, myResponse,) = sm.GetService('calendar').GetMyResponseIconFromID(eventInfo.eventID, long=0, getDeleted=eventInfo.isDeleted)
            hint = sm.GetService('calendar').GetResponseType().get(myResponse, mls.UI_GENERIC_UNKNOWN)
            data = util.KeyVal()
            data.label = eventInfo.eventTitle
            data.eventInfo = eventInfo
            data.icon = icon
            data.hint = hint
            data.response = myResponse
            entry = listentry.Get(self.listentryClass, data=data)
            return entry



    def OnMoreClick(self, *args):
        sm.GetService('calendar').OpenSingleDayWnd(self.header, '', '', '', self.events, isADay=0)




class UpdateEventsList(EventList):
    __guid__ = 'uicls.UpdateEventsList'

    def GetEventEntryTuple(self, eventKV, *args):
        entry = self.GetEventEntry(eventKV)
        if (entry is None):
            return 
        else:
            return (eventKV.dateModified, entry)



    def GetSortOrder(self, *args):
        return 1




class CalendarListEntry(listentry.Generic):
    __guid__ = 'listentry.CalendarListEntry'
    __notifyevents__ = []

    def Startup(self, *args):
        self.sr.fill = uicls.Frame(parent=self, name='fill', frameConst=uiconst.FRAME_FILLED_SHADOW_CORNER0, color=(1.0, 1.0, 1.0, 0.05))
        self.sr.statusIconCont = uicls.Container(name='statusIconCont', parent=self, align=uiconst.TOPLEFT, pos=(0, 0, 16, 16))
        self.sr.tagIconCont = uicls.Container(name='statusIconCont', parent=self, align=uiconst.TOPRIGHT, pos=(0, 0, 16, 16))
        uicls.Frame(parent=self.sr.statusIconCont)
        listentry.Generic.Startup(self, args)
        self.sr.label.autoPos = 0
        self.sr.label.top = 2
        self.sr.label.mmbold = 1.0
        self.sr.timeLabel = uicls.Label(text='', parent=self, left=20, top=14, state=uiconst.UI_DISABLED, align=uiconst.TOPLEFT, singleline=1, color=(0.7, 0.7, 0.7, 0.75))
        uiutil.SetOrder(self.sr.fill, -1)
        sm.RegisterNotify(self)



    def Load(self, node):
        listentry.Generic.Load(self, node)
        self.sr.label.left = 20
        eventInfo = node.eventInfo
        hint = self.GetEventHint(eventInfo, node.response)
        self.hint = hint
        if (eventInfo.importance > 0):
            label = self.sr.node.label
            newLabel = ('<color=red>!</color> %s' % label)
            self.sr.label.text = newLabel
        self.SetTime(eventInfo.eventDateTime)
        self.LoadStatusIcon()
        sm.GetService('calendar').LoadTagIconInContainer(eventInfo.flag, self.sr.tagIconCont)



    def GetMenu(self, *args):
        eventInfo = self.sr.node.eventInfo
        m = sm.GetService('calendar').GetEventMenu(eventInfo, self.sr.node.response)
        return m



    def GetEventHint(self, eventInfo, myResponse, *args):
        hint = sm.GetService('calendar').GetEventHint(eventInfo, myResponse)
        return hint



    def _OnClose(self):
        sm.UnregisterNotify(self)



    def LoadStatusIcon(self, *args):
        data = self.sr.node
        uiutil.Flush(self.sr.statusIconCont)
        iconPath = uix.GetIconPath(data.icon)
        hint = data.hint
        icon = uicls.Icon(icon=iconPath, parent=self.sr.statusIconCont, align=uiconst.CENTER, pos=(0, 2, 16, 16))
        icon.hint = hint



    def GetHeight(self, *args):
        (node, width,) = args
        node.height = 30
        return node.height



    def SetTime(self, eventDateTime, *args):
        self.sr.timeLabel.text = util.FmtDate(eventDateTime, 'ls')



    def _OnDblClick(self, *args):
        sm.GetService('calendar').OpenEventWnd(self.sr.node.eventInfo)




class CalendarUpdatedEntry(CalendarListEntry):
    __guid__ = 'listentry.CalendarUpdatedEntry'

    def GetEventHint(self, eventInfo, myResponse, *args):
        hint = ('%s<br>%s<br>%s' % (util.FmtDate(eventInfo.eventDateTime, 'ls'),
         eventInfo.eventTitle,
         ('%s: %s ' % (mls.UI_CAL_LASTUPDATED, util.FmtDate(eventInfo.dateModified, 'ls')))))
        return hint




